/*
 * This program is free software; you can redistribute it and/or modify it under the 
 * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software 
 * Foundation.
 *
 * You should have received a copy of the GNU Lesser General Public License along with this 
 * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html 
 * or from the Free Software Foundation, Inc., 
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Lesser General Public License for more details.
 *
 * Copyright 2008 Pentaho Corporation.  All rights reserved.
 *
 * @author Will Gorman (wgorman@pentaho.com)
 */
package org.pentaho.actioneditor.client.processpanels;

import org.pentaho.actioneditor.client.ActionEditor;
import org.pentaho.actioneditor.client.util.EventRichFlexTable;
import org.pentaho.actionsequence.dom.ActionSequenceDocument;
import org.pentaho.actionsequence.dom.IActionSequenceInput;
import org.pentaho.actionsequence.dom.IActionSequenceInputSource;

import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.FocusListener;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.MenuBar;
import com.google.gwt.user.client.ui.MenuItem;
import com.google.gwt.user.client.ui.SourcesTableEvents;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.TreeItem;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

public class InputPanel {
  
  int selectedSourceRow = -1;
  final InputUI iui = new InputUI();
  TreeItem parentTreeItem;
  IActionSequenceInput input;
  ActionEditor actionEditor;
  
  public InputPanel(IActionSequenceInput actionSequenceInput, ActionEditor actionEditor, TreeItem parentTreeItem) {
    this.parentTreeItem = parentTreeItem;
    this.actionEditor = actionEditor;
    this.input = actionSequenceInput;
  }
  
  public VerticalPanel getRoot() {
    return iui.getRoot();
  }
  
  public void init() {
    // display the item's details pane
    
    iui.setAddSourceCommand(new InputUI.ItemCommand() {
      public void execute(String text) {
        input.addSource(text, input.getName());
        renderSourceTable();
      }
    });
    
    iui.init();
    
    iui.getName().setText(input.getName());
    iui.getHasDefaultValue().setChecked(input.getDefaultValue() != null);

    renderDefaultValueWidget(input, iui);
    
    for (int i = 0; i < iui.getType().getItemCount(); i++) {
      if (iui.getType().getItemText(i).equals(input.getType())) {
        iui.getType().setSelectedIndex(i);    
      }
    }
    iui.getType().addChangeListener(new ChangeListener() {
      public void onChange(Widget sender) {
        System.out.println("TYPE CHANGE: " + iui.getType().getItemText(iui.getType().getSelectedIndex()));
        input.setType(iui.getType().getItemText(iui.getType().getSelectedIndex()));
        renderDefaultValueWidget(input, iui);
        parentTreeItem.setText(iui.getName().getText() + " (" + iui.getType().getItemText(iui.getType().getSelectedIndex()) + ")");
        actionEditor.updateOutputMenuBar();
      }
    });
    
    iui.getName().addChangeListener(new ChangeListener() {
      public void onChange(Widget sender) {
        input.setName(iui.getName().getText());
        parentTreeItem.setText(iui.getName().getText() + " (" + iui.getType().getItemText(iui.getType().getSelectedIndex()) + ")");
        actionEditor.updateOutputMenuBar();
      }
    });

    iui.getHasDefaultValue().addClickListener(new ClickListener(){
      public void onClick(Widget sender) {
        System.out.println("hasDefaultValue CLICKED");
        // this depends on the type
        if (iui.getHasDefaultValue().isChecked()) {
          if (input.getDefaultValue() == null) {
            input.setDefaultValue("");
          }
        } else {
          input.setDefaultValue((String)null);
        }
        renderDefaultValueWidget(input, iui);
      }
    });

    // Double click on origin results in a drop down, double click on name results in a text box.
    iui.getDeleteSource().setCommand(new Command() {
      public void execute() {
        if (selectedSourceRow != -1 && input.getSources().length > selectedSourceRow) {
          input.getSources()[selectedSourceRow].delete();
          // re-render table
          renderSourceTable();
        }
      }
    });
    
    iui.getSourceUp().setCommand(new Command() {
      public void execute() {
        if (selectedSourceRow != -1 && selectedSourceRow != 0) {
          IActionSequenceInputSource source = input.getSources()[selectedSourceRow];
          source.delete();
          input.addSource(selectedSourceRow - 1, source.getOrigin(), source.getName());
          int newSelectedSourceRow = selectedSourceRow - 1;
          renderSourceTable();
          setSelectedSourceRow(newSelectedSourceRow);
        }
      }
    });

    iui.getSourceDown().setCommand(new Command() {
      public void execute() {
        
        if (selectedSourceRow != -1 && selectedSourceRow != input.getSources().length - 1) {
          IActionSequenceInputSource source = input.getSources()[selectedSourceRow];
          source.delete();
          int newSelectedSourceRow = selectedSourceRow + 1;
          if (input.getSources().length == newSelectedSourceRow) {
            input.addSource(source.getOrigin(), source.getName());
          } else {
            input.addSource(selectedSourceRow + 1, source.getOrigin(), source.getName());
          }
          renderSourceTable();
          setSelectedSourceRow(newSelectedSourceRow);
        }
      }
    });

    renderSourceTable();
  }
  
  public void renderDefaultValueWidget(final IActionSequenceInput input, final InputUI iui) {
    
    iui.getDefaultValueBox().clear();
    
    String elementType = input.getType();
    if (elementType.equals(ActionSequenceDocument.STRING_TYPE)/*)  {
//      TextBox text = new TextBox();
//      iui.getDefaultValueBox().add(text);
    } else if (*/ || elementType.equals(ActionSequenceDocument.LONG_TYPE)
        || elementType.equals(ActionSequenceDocument.INTEGER_TYPE) 
        || elementType.equals(ActionSequenceDocument.BIGDECIMAL_TYPE)) {
      // TODO: Verify numeric if necessary
      final TextBox text = new TextBox();
      if (input.getDefaultValue() != null) {
        text.setText(input.getDefaultValue().toString());
      }
      text.addChangeListener(new ChangeListener() {
        public void onChange(Widget sender) {
          // hopefully this doesn't trigger an event
          System.out.println("Changing Default Value...");
          if (!iui.getHasDefaultValue().isChecked()) {
            iui.getHasDefaultValue().setChecked(true);
          }
          input.setDefaultValue(text.getText());
        }
      });
      iui.getDefaultValueBox().add(text);
    } else if (elementType.equals(ActionSequenceDocument.STRING_LIST_TYPE)) {
      // TODO: IMPLEMENT
      FlexTable table = new FlexTable();
      table.setWidget(0, 0, new Label("<<Add Item>>"));
      iui.getDefaultValueBox().add(table);
    } else if (elementType.equals(ActionSequenceDocument.PROPERTY_MAP_TYPE)) {
      // TODO: IMPLEMENT
      TableEditorUI tableEditor = new TableEditorUI();
      tableEditor.init();
      tableEditor.getEditorLabel().setText("");
      tableEditor.getAddList().addItem(new MenuItem("Add Row", (Command)null));
      MenuItem insertRow = new MenuItem("Insert Row", (Command)null);
      MenuBar insertRowBar = new MenuBar(true);
      insertRowBar.addItem("Before", (Command)null);
      insertRowBar.addItem("After", (Command)null);
      insertRow.setSubMenu(insertRowBar);
      tableEditor.getAddList().addItem(insertRow);
      tableEditor.getTable().getRowFormatter().setStyleName(0, "gwt-HeaderRow");
      tableEditor.getTable().setWidget(0,0, new Label("Keys")); // style to be gray
      tableEditor.getTable().setWidget(0,1, new Label("Values")); // style to be gray
      iui.getDefaultValueBox().add(tableEditor.getRoot());
    } else if (elementType.equals(ActionSequenceDocument.PROPERTY_MAP_LIST_TYPE) || elementType.equals(ActionSequenceDocument.RESULTSET_TYPE)) {
      // TODO: IMPLEMENT
      TableEditorUI tableEditor = new TableEditorUI();
      tableEditor.init();
      tableEditor.getEditorLabel().setText("");
      tableEditor.getAddList().addItem(new MenuItem("Add Row", (Command)null));
      tableEditor.getAddList().addItem(new MenuItem("Add Column", (Command)null));
      MenuItem insertRow = new MenuItem("Insert Row", (Command)null);
      MenuBar insertRowBar = new MenuBar(true);
      insertRowBar.addItem("Before", (Command)null);
      insertRowBar.addItem("After", (Command)null);
      insertRow.setSubMenu(insertRowBar);
      tableEditor.getAddList().addItem(insertRow);
      MenuItem insertCol = new MenuItem("Insert Column", (Command)null);
      MenuBar insertColBar = new MenuBar(true);
      insertRowBar.addItem("Before", (Command)null);
      insertRowBar.addItem("After", (Command)null);
      insertRow.setSubMenu(insertColBar);
      tableEditor.getAddList().addItem(insertCol);
      MenuBar deleteMenu = new MenuBar(true);
      deleteMenu.addItem("Delete Row", (Command)null);
      deleteMenu.addItem("Delete Column", (Command)null);
      tableEditor.getDelete().setSubMenu(deleteMenu);
      
      tableEditor.getTable().setWidget(0,0, new Label("")); // style to be gray
      iui.getDefaultValueBox().add(tableEditor.getRoot());
    }
  }

  EventRichFlexTable sourceTable;
  
  public void renderSourceTable() {
    IActionSequenceInputSource sources[] = input.getSources();
    selectedSourceRow = -1;

   iui.getTableScroller().clear();
   sourceTable = new EventRichFlexTable();
   sourceTable.setWidth("240px");
   

   sourceTable.setWidget(0, 0, new Label("Origin"));
    sourceTable.setWidget(0, 1, new Label("Name"));
    sourceTable.getRowFormatter().setStylePrimaryName(0, "gwt-HeaderRow");
    
    for (int i = 0; i < sources.length; i++) {
      sourceTable.getRowFormatter().setStylePrimaryName(i+1, "gwt-DataRow" + ((i % 2 == 0) ? "Even" : "Odd"));
      sourceTable.setWidget(i + 1, 0, new Label(sources[i].getOrigin()));
      sourceTable.setWidget(i + 1, 1, new Label(sources[i].getName()));
    }    
    
    iui.getTableScroller().setWidget(sourceTable);
    
    sourceTable.addTableListener(new EventRichFlexTable.EventRichTableListener() {
      public void onCellClicked(SourcesTableEvents sender, int row, int cell) {
        System.out.println("CLICKED : " + row + ", " + cell + ", style=" + sourceTable.getRowFormatter().getStyleName(row) + ", " + sourceTable.getRowFormatter().getStylePrimaryName(row));
        if (row != 0) {
          setSelectedSourceRow(row - 1);
        }
      }

      public void onCellDblClicked(SourcesTableEvents sender, int row, int cell) {
        System.out.println("DOUBLE CLICKED : " + row + ", " + cell + ", style=" + sourceTable.getRowFormatter().getStyleName(row) + ", " + sourceTable.getRowFormatter().getStylePrimaryName(row));
        if (selectedSourceRow != -1) {
          sourceTable.setWidget(selectedSourceRow + 1, 0, new Label(input.getSources()[selectedSourceRow].getOrigin()));
          sourceTable.setWidget(selectedSourceRow + 1, 1, new Label(input.getSources()[selectedSourceRow].getName()));
        }
        if (row != 0) {
          setSelectedSourceRow(row - 1);
          if (cell == 0) {
            
            System.out.println("RENDER DROPDOWN");
            final ListBox listbox = new ListBox();
            listbox.addItem("request");
            listbox.addItem("session");
            listbox.addItem("global");
            listbox.addItem("runtime");
            listbox.addItem("security");
            
            listbox.addFocusListener(new FocusListener() {

              public void onFocus(Widget sender) {
                System.out.println("LIST BOX GAINED FOCUS");
              }

              public void onLostFocus(Widget sender) {
                // get the values of the pulldown or text box
                System.out.println("LIST FOCUS LOST: " + listbox.getItemText(listbox.getSelectedIndex()));
                input.getSources()[selectedSourceRow].setOrigin(listbox.getItemText(listbox.getSelectedIndex()));
                sourceTable.setWidget(selectedSourceRow + 1, 0, new Label(input.getSources()[selectedSourceRow].getOrigin()));
                sourceTable.setWidget(selectedSourceRow + 1, 1, new Label(input.getSources()[selectedSourceRow].getName()));
              }
              
            });
            
            for (int i = 0; i < listbox.getItemCount(); i++) {
              String text = listbox.getItemText(i);
              if (text.equals(input.getSources()[row - 1].getOrigin())) {
                listbox.setSelectedIndex(i);
                break;
              }
            }
            
            listbox.addChangeListener(new ChangeListener() {
              public void onChange(Widget sender) {
                input.getSources()[selectedSourceRow].setOrigin(listbox.getItemText(listbox.getSelectedIndex()));
              }
            });

            // TODO: NEED TO CLEAR OUT DROP DOWN ONCE FOCUS IS LOST
            
            sourceTable.setWidget(row, cell, listbox);
            listbox.setFocus(true);
            // selectedSourceCell = cell;
          } else if (cell == 1) {
            final TextBox text = new TextBox();
            text.setText(input.getSources()[selectedSourceRow].getName());
            text.addChangeListener(new ChangeListener() {
              public void onChange(Widget sender) {
                System.out.println("Text Changed : " + text.getText());
                input.getSources()[selectedSourceRow].setName(text.getText());
              }
            });
            
            text.addFocusListener(new FocusListener() {
              public void onFocus(Widget sender) {
                System.out.println("TEXT BOX FOCUS");
              }

              public void onLostFocus(Widget sender) {
                System.out.println("Text Focus Lost : " + text.getText());
                input.getSources()[selectedSourceRow].setName(text.getText());
                sourceTable.setWidget(selectedSourceRow + 1, 0, new Label(input.getSources()[selectedSourceRow].getOrigin()));
                sourceTable.setWidget(selectedSourceRow + 1, 1, new Label(input.getSources()[selectedSourceRow].getName()));
              }
            });
            System.out.println("RENDER TEXTBOX");
            sourceTable.setWidget(row, cell, text);
            text.setFocus(true);
            // selectedSourceCell = cell;
          }
        }
        
      }
    });
  }

  public void setSelectedSourceRow(int row) {
    System.out.println("SET SELECTED SOURCE ROW: " + row + " (was " + selectedSourceRow + ")");
    if (selectedSourceRow == row) {
      return;
    }
    if (selectedSourceRow != -1) {
      // clear out any widgets
      sourceTable.setWidget(selectedSourceRow + 1, 0, new Label(input.getSources()[selectedSourceRow].getOrigin()));
      sourceTable.setWidget(selectedSourceRow + 1, 1, new Label(input.getSources()[selectedSourceRow].getName()));
      sourceTable.getRowFormatter().setStyleName(selectedSourceRow + 1, "gwt-DataRow" + ((selectedSourceRow % 2 == 0) ? "Even" : "Odd"));
    }
    selectedSourceRow = row;
    sourceTable.getRowFormatter().setStyleName(row + 1, "gwt-DataRowSelected");
  }
  
}
